#include <stdlib.h>
#ifdef _MSC_VER
#include <Windows.h>
#else
#include <stdio.h>
#include <ctype.h>
#include <wctype.h>
#include <string.h>
#endif
#include "String.h"

namespace zl
{
	zint  atoi(const std::string& string)
	{
		char* endptr = 0;
		return  strtol(string.c_str(), &endptr, 10);
	}

	zint wtoi(const std::wstring& string)
	{
		wchar_t* endptr = 0;
		return wcstol(string.c_str(), &endptr, 10);
	}

#ifdef _MSC_VER
	__int64 atoi64(const std::string& string)
	{
		char* endptr = 0;
		__int64 result = _strtoi64(string.c_str(), &endptr, 10);
		return result;
	}

	__int64 wtoi64(const std::wstring& string)
	{
		wchar_t* endptr = 0;
		__int64 result = _wcstoi64(string.c_str(), &endptr, 10);
		return result;
	}
#else
	long long atoi64(const std::string& string)
	{
		char* endptr = 0;
		return strtoll(string.c_str(), &endptr, 10);
	}

	long long wtoi64(const std::wstring& string)
	{
		wchar_t* endptr = 0;
		return wcstoll(string.c_str(), &endptr, 10);
	}
#endif

	zuint atou(const std::string& string)
	{
		char* endptr = 0;
		return strtoul(string.c_str(), &endptr, 10);
	}

	zuint wtou(const std::wstring& string)
	{
		wchar_t* endptr = 0;
		return wcstoul(string.c_str(),&endptr, 10);
	}

#ifdef _MSC_VER
	unsigned __int64 atou64(const std::string& string, bool& success)
	{
		char* endptr = 0;
		unsigned __int64 result = _strtoui64(string.c_str(), &endptr, 10);
		return result;
	}

	unsigned __int64 wtou64_test(const std::wstring& string, bool& success)
	{
		wchar_t* endptr = 0;
		unsigned __int64 result = _wcstoui64(string.c_str(), &endptr, 10);
		return result;
	}
#else
	unsigned long long atou64(const std::string& string)
	{
		char* endptr = 0;
		return strtoull(string.c_str(), &endptr, 10);
	}

	unsigned long long wtou64(const std::wstring& string)
	{
		wchar_t* endptr = 0;
		return wcstoull(string.c_str(), &endptr, 10);
	}
#endif

	double atof(const std::string& string)
	{
		char* endptr = 0;
		return strtod(string.c_str(), &endptr);
	}

	double wtof(const std::wstring& string)
	{
		wchar_t* endptr = 0;
		return wcstod(string.c_str(), &endptr);
	}

	std::string itoa(zint number)
	{
		char buffer[100] = { 0 };
#ifdef _MSC_VER
		_itoa_s(number, buffer, sizeof(buffer)/sizeof(*buffer), 10);
#else
#ifdef ZL_64
		sprintf(buffer, "%ld", (long long)number);
#else
		sprintf(buffer, "%d", number);
#endif
#endif
		return buffer;
	}

	std::wstring itow(zint number)
	{
#ifdef _MSC_VER
		wchar_t buffer[100];
		_itow_s(number, buffer, sizeof(buffer)/sizeof(*buffer), 10);
		return buffer;
#else
		return atow(itoa(number));
#endif
	}

#ifdef _MSC_VER
	std::string i64toa(__int64 number)
	{
		char buffer[100];
		_i64toa_s(number, buffer, sizeof(buffer)/sizeof(*buffer), 10);
		return buffer;
	}

	std::wstring i64tow(__int64 number)
	{
		wchar_t buffer[100];
		_i64tow_s(number, buffer, sizeof(buffer)/sizeof(*buffer), 10);
		return buffer;
	}
#else
    std::string i64toa(long long number)
	{
		char buffer[100] = { 0 };
		sprintf(buffer, "%ld", (long int)number);
		return buffer;
	}

	std::wstring i64tow(long long number)
	{
		return atow(i64toa(number));
	}
#endif

	std::string utoa(zuint number)
	{
		char buffer[100] = { 0 };
#ifdef _MSC_VER
		_ui64toa_s(number, buffer, sizeof(buffer)/sizeof(*buffer), 10);
#else
		sprintf(buffer, "%u", (unsigned int)number);
#endif	
		return buffer;
	}

	std::wstring utow(zuint number)
	{
#ifdef _MSC_VER
		wchar_t buffer[100];
		_ui64tow_s(number, buffer, sizeof(buffer)/sizeof(*buffer), 10);
		return buffer;
#else
		return atow(utoa(number));
#endif
	}

#ifdef _MSC_VER
	std::string u64toa(unsigned __int64 number)
	{
		char buffer[100];
		_ui64toa_s(number, buffer, sizeof(buffer)/sizeof(*buffer), 10);
		return buffer;
	}

	std::wstring u64tow(unsigned __int64 number)
	{
		wchar_t buffer[100];
		_ui64tow_s(number, buffer, sizeof(buffer)/sizeof(*buffer), 10);
		return buffer;
	}
#else
	std::string u64toa(unsigned long long number)
	{
		char buffer[100] = { 0 };
		sprintf(buffer, "%lu", (long unsigned int)number);
		return buffer;
	}

	std::wstring u64tow(unsigned long long number)
	{
		return atow(u64toa(number));
	}
#endif

	std::string ftoa(double number)
	{
		char buffer[100] = { 0 };
#ifdef _MSC_VER
		_gcvt_s(buffer, 100, number, 30);
		zint len = (zint)strlen(buffer);
		if (buffer[len - 1] == '.')
		{
			buffer[len - 1] = '\0';
		}
#else
		sprintf(buffer, "%lf", number);
#endif
		return buffer;
	}

	std::wstring ftow(double number)
	{
		return atow(ftoa(number));
	}

	zint _wtoa(const wchar_t* w, char*a, zint chars)
	{
#ifdef _MSC_VER
		return WideCharToMultiByte(CP_THREAD_ACP, 0, w, -1, a, (int)(a ? chars : 0), 0, 0);
#else
		return wcstombs(a, w, chars);
#endif
	}


	std::string wtoa(const std::wstring& string)
	{		
#ifdef _MSC_VER
		zint len = _wtoa(string.c_str(), 0, 0);
		char* buffer=new char[len];
#else
		zint len = string.length();
		char* buffer = new char[len * 5 + 1];
		memset(buffer, 0, len * 5 + 1);
#endif
		_wtoa(string.c_str(), buffer, len * 5 + 1);
		std::string s = buffer;
		delete[]buffer;
		return s;
	}

	zint _atow(const char* a, wchar_t* w, zint chars)
	{
#ifdef _MSC_VER
		return MultiByteToWideChar(CP_THREAD_ACP, 0, a, -1, w, (int)(w?chars:0));
#else
		return mbstowcs(w, a, chars);
#endif
	}

	std::wstring atow(const std::string& string)
	{
#ifdef _MSC_VER
		zint len = _atow(string.c_str(),0,0);
		wchar_t* buffer=new wchar_t[len];
#else
		zint len = string.length();
		wchar_t* buffer = new wchar_t[5 * len + 1];
		memset(buffer, 0, (5 * len + 1) * 4);
#endif
		_atow(string.c_str(), buffer,(int)len);
		std::wstring s = buffer;
		delete[]buffer;
		return s;
	}

	std::string alower(const std::string& string)
	{
#ifdef _MSC_VER
		std::string result = string.c_str();
		_strlwr_s((char*)result.c_str(), result.length() + 1);
#else
		char* buffer = new char[string.length() + 1];
		for (zint i = 0; i<string.length(); i++)
		{
			buffer[i] = tolower((string.c_str())[i]);
		}
		std::string result = buffer;
		delete[]buffer;
#endif
		return result;
	}

	std::wstring wlower(const std::wstring& string)
	{
#ifdef _MSC_VER
		std::wstring result = string.c_str();
		_wcslwr_s((wchar_t*)result.c_str(), result.length() + 1);
#else
		wchar_t* buffer=new wchar_t[string.length()+1];
		for (zint i = 0; i<string.length(); i++)
		{
			buffer[i] = towlower((string.c_str())[i]);
		}
		std::wstring result = buffer;
		delete[]buffer;
#endif
		return result;
	}

	std::string aupper(const std::string& string)
	{
#ifdef _MSC_VER
		std::string result = string.c_str();
		_strupr_s((char*)result.c_str(), result.length() + 1);
#else
		char* buffer=new char[string.length()+1];
		for (zint i = 0; i<string.length(); i++)
		{
			buffer[i] = toupper((string.c_str())[i]);
		}
		std::string result = buffer;
		delete[]buffer;
#endif
		return result;
	}

	std::wstring wupper(const std::wstring& string)
	{
#ifdef _MSC_VER
		std::wstring result = string.c_str();
		_wcsupr_s((wchar_t*)result.c_str(), result.length() + 1);
#else
		wchar_t* buffer=new wchar_t[string.length()+1];
		for (zint i = 0; i<string.length(); i++)
		{
			buffer[i] = towupper((string.c_str())[i]);
		}
		std::wstring result = buffer;
		delete[]buffer;
#endif
		return result;
	}


};